﻿#include "ProtoHeader-c.h"
#include "AvType.h"


CMsgHead* CMsgHeadNew()
{
	CMsgHead* _this = (CMsgHead*)malloc(sizeof(CMsgHead));
	if (NULL == _this) {
		return NULL;
	}
	memset(_this->m_Payload, 0x00, sizeof(_this->m_Payload));
	memset(_this->m_UserData, 0x00, sizeof(_this->m_UserData));
	_this->m_UserDataLength = 0;

	_this->m_BufferSize = 1024 * 2;
	_this->m_Buffer = (unsigned char*)malloc(sizeof(unsigned char) * _this->m_BufferSize);
	_this->m_BufferLength = 0;
	memset(_this->m_Buffer, 0x00, _this->m_BufferSize);
	{
		_this->m_MsgHead = (_MsgHeadInfo*)_this->m_Buffer;
		_this->m_MsgHead->_MsgLength = 0;
		_this->m_MsgHead->_MsgUserDataLength = 0;
		_this->m_MsgHead->_MsgPayloadCount = 0;
	}

	return _this;
}
void CMsgHeadRelease(CMsgHead* _this)
{
	_this->m_UserDataLength = 0;
	memset(_this->m_Payload, 0x00, sizeof(_this->m_Payload));
	memset(_this->m_UserData, 0x00, sizeof(_this->m_UserData));
	_this->m_UserDataLength = 0;

	if (NULL != _this->m_Buffer) {
		free(_this->m_Buffer);
		_this->m_Buffer = NULL;
	}

	_this->m_BufferLength = 0;
	_this->m_BufferSize = 0;
	_this->m_MsgHead = NULL;
	free(_this);
}

void Zero(CMsgHead* _this)
{
	_this->m_UserDataLength = 0;
	_this->m_BufferLength = 0;
	memset(_this->m_Payload, 0x00, sizeof(_this->m_Payload));
	memset(_this->m_UserData, 0x00, sizeof(_this->m_UserData));
	{
		_this->m_MsgHead = (_MsgHeadInfo*)_this->m_Buffer;
		_this->m_MsgHead->_MsgLength = 0;
		_this->m_MsgHead->_MsgUserDataLength = 0;
		_this->m_MsgHead->_MsgPayloadCount = 0;
	}
}
void SetCommand(CMsgHead* _this, unsigned int Command)
{
	_this->m_MsgHead->_MsgCommand = Command;
}
int SetPayLoad(CMsgHead* _this, unsigned short PayLoadLength)
{
	if (_this->m_MsgHead->_MsgPayloadCount == CMSGHEAD_MAX_PAYLOADCOUNT || PayLoadLength == 0) {
		return -1;
	}
	_this->m_Payload[_this->m_MsgHead->_MsgPayloadCount++] = PayLoadLength;
	return 0;
}
int SetUserData(CMsgHead* _this, void* Data, unsigned short length)
{
	if (length > CMSGHEAD_MAX_USERDATA) {
		return -1;
	}

	memcpy(_this->m_UserData, Data, length);
	_this->m_UserDataLength = length;

	return 0;
}

int ByteSize(CMsgHead* _this)
{
	return _this->m_BufferLength;
}
char* Serialize(CMsgHead* _this)
{
	_this->m_MsgHead->_MsgSync = CMSGHEAD_MSG_SYNC;
	_this->m_MsgHead->_MsgVersion = CMSGHEAD_MSG_VERSION;
	_this->m_MsgHead->_MsgLength = sizeof(_MsgHeadInfo);
	_this->m_MsgHead->_MsgUserDataLength = 0;
	_this->m_BufferLength = sizeof(_MsgHeadInfo);
	if (_this->m_UserData != NULL && _this->m_UserDataLength > 0) {
		memcpy(&_this->m_Buffer[sizeof(_MsgHeadInfo)], _this->m_UserData, _this->m_UserDataLength);
		_this->m_MsgHead->_MsgLength += _this->m_UserDataLength;
		_this->m_MsgHead->_MsgUserDataLength = _this->m_UserDataLength;
		_this->m_BufferLength += _this->m_UserDataLength;
	}
	_MsgPayloadInfo* PayloadInfo = (_MsgPayloadInfo*)&_this->m_Buffer[_this->m_MsgHead->_MsgLength];
	_this->m_MsgHead->_MsgLength += sizeof(_MsgPayloadInfo) * _this->m_MsgHead->_MsgPayloadCount;
	_this->m_BufferLength += sizeof(_MsgPayloadInfo) * _this->m_MsgHead->_MsgPayloadCount;
	int i = 0;
	for (i = 0; i < _this->m_MsgHead->_MsgPayloadCount; i++) {
		PayloadInfo[i].PayLoadStart = _this->m_MsgHead->_MsgLength;
		PayloadInfo[i].PayLoadLength = _this->m_Payload[i];
		_this->m_MsgHead->_MsgLength += _this->m_Payload[i];
	}
	return (char*)_this->m_Buffer;
}

unsigned int Command(CMsgHead* _this)
{
	return _this->m_MsgHead->_MsgCommand;
}
unsigned int Version(CMsgHead* _this)
{
	return _this->m_MsgHead->_MsgVersion;
}
int bWithUserData(CMsgHead* _this)
{
	if (_this->m_MsgHead->_MsgUserDataLength > 0) {
		return 0;
	}
	else {
		return -1;
	}
}

void ParseData(CMsgHead* _this, void* data, int len)
{
	if (_this->m_BufferLength + len > _this->m_BufferSize) {
		_this->m_BufferSize = _this->m_BufferLength + len;
		unsigned char* pBuffer = (unsigned char*)malloc(sizeof(unsigned char) * _this->m_BufferSize);
		memcpy(pBuffer, _this->m_Buffer, _this->m_BufferLength);

		free(_this->m_Buffer);
		_this->m_Buffer = pBuffer;
		_this->m_MsgHead = (_MsgHeadInfo*)_this->m_Buffer;
	}
	memcpy(&_this->m_Buffer[_this->m_BufferLength], data, len);
	_this->m_BufferLength += len;
}
int bHaveMsg(CMsgHead* _this)
{
	if (_this->m_BufferLength < sizeof(_MsgHeadInfo)) {
		return -1;
	}

	if (_this->m_MsgHead->_MsgSync != CMSGHEAD_MSG_SYNC) {
		_this->m_BufferLength = 0;
		return -1;
	}

	if (_this->m_MsgHead->_MsgLength <= _this->m_BufferLength) {
		return 0;
	}
	else {
		return -1;
	}
}
void PopOneMsg(CMsgHead* _this)
{
	int msgLength = _this->m_MsgHead->_MsgLength;
	if (_this->m_BufferLength - msgLength > 0) {
		memmove(_this->m_Buffer, (char*)_this->m_Buffer + msgLength, _this->m_BufferLength - msgLength);
	}
	_this->m_BufferLength -= msgLength;
}

void* UserData(CMsgHead* _this)
{
	if (_this->m_MsgHead->_MsgUserDataLength > 0) {
		return _this->m_Buffer + sizeof(_MsgHeadInfo);
	}
	else {
		return NULL;
	}
}
unsigned short	UserDataLength(CMsgHead* _this)
{
	return _this->m_MsgHead->_MsgUserDataLength;
}

char* PayLoadData(CMsgHead* _this, int index)
{
	if (index >= _this->m_MsgHead->_MsgPayloadCount) {
		return NULL;
	}
	_MsgPayloadInfo* PayloadInfo = (_MsgPayloadInfo*)(_this->m_Buffer + sizeof(_MsgHeadInfo) + _this->m_MsgHead->_MsgUserDataLength + sizeof(_MsgPayloadInfo) * index);
	return (char*)_this->m_Buffer + PayloadInfo->PayLoadStart;
}
unsigned short   PayLoadLength(CMsgHead* _this, int index)
{
	if (index >= _this->m_MsgHead->_MsgPayloadCount) {
		return 0;
	}
	_MsgPayloadInfo* PayloadInfo = (_MsgPayloadInfo*)(_this->m_Buffer + sizeof(_MsgHeadInfo) + _this->m_MsgHead->_MsgUserDataLength + sizeof(_MsgPayloadInfo) * index);
	return PayloadInfo->PayLoadLength;
}
unsigned short  PayLoadCount(CMsgHead* _this)
{
	return _this->m_MsgHead->_MsgPayloadCount;
}
